// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "AdvancedCharacterMovementComponent.generated.h"

// 声明日志分类
DECLARE_LOG_CATEGORY_EXTERN(LogAdvancedMovement, Log, All);

/**
 * 高级角色移动组件
 * 扩展标准角色移动组件，增加冲刺、地面检测增强等功能
 */
UCLASS()
class EMPTYLAND_API UAdvancedCharacterMovementComponent : public UCharacterMovementComponent
{
    GENERATED_BODY()

public:
    // 构造函数
    UAdvancedCharacterMovementComponent();

    // 重写移动更新函数
    virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

    /**
     * 设置冲刺状态
     * @param bNewSprinting 是否开启冲刺
     */
    UFUNCTION(BlueprintCallable, Category = "Character Movement")
    void SetSprinting(bool bNewSprinting);

    /**
     * 获取当前是否在冲刺
     * @return 冲刺状态
     */
    UFUNCTION(BlueprintCallable, Category = "Character Movement")
    bool IsSprinting() const; 

    /**
     * 获取最大冲刺时长
     * @return 冲刺时长（秒）
     */
    UFUNCTION(BlueprintCallable, Category = "Character Movement")
    float GetMaxSprintTime() const;

    /**
     * 获取当前剩余冲刺时间
     * @return 剩余冲刺时间（秒）
     */
    UFUNCTION(BlueprintCallable, Category = "Character Movement")
    float GetCurrentSprintTimeRemaining() const;

protected:
    // 重写计算移动速度的函数
    virtual float GetMaxSpeed() const override;

    // 重写更新角色移动模式的函数
    virtual void UpdateCharacterStateBeforeMovement(float DeltaTime) override;

private:
    // 是否正在冲刺
    UPROPERTY(Transient) 
    bool bIsSprinting;

    // 冲刺速度倍率
    UPROPERTY(EditDefaultsOnly, Category = "Sprint", meta = (AllowPrivateAccess = "true"))
    float SprintSpeedMultiplier;

    // 最大冲刺时长
    UPROPERTY(EditDefaultsOnly, Category = "Sprint", meta = (AllowPrivateAccess = "true"))
    float MaxSprintTime;

    // 冲刺恢复速率（每秒恢复的比例）
    UPROPERTY(EditDefaultsOnly, Category = "Sprint", meta = (AllowPrivateAccess = "true"))
    float SprintRecoveryRate;

    // 当前剩余冲刺时间
    UPROPERTY(Transient)
    float CurrentSprintTimeRemaining;

    // 地面检测额外射线数量（增强地形适应性）
    UPROPERTY(EditDefaultsOnly, Category = "Ground Detection", meta = (AllowPrivateAccess = "true"))
    int32 GroundCheckRayCount;

    /**
     * 更新冲刺状态
     * @param DeltaTime 帧时间
     */
    void UpdateSprint(float DeltaTime);

    /**
     * 增强的地面检测
     * @return 是否在地面上
     */
    bool EnhancedGroundCheck();
};